<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Printing messages and asking questions &mdash; The Logtalk Handbook v3.93.0-b01 documentation</title>
      <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
      <link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=19f00094" />
      <link rel="stylesheet" type="text/css" href="../_static/css/custom.css?v=396eccfe" />

  
  <!--[if lt IE 9]>
    <script src="../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script src="../_static/jquery.js?v=5d32c60e"></script>
        <script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="../_static/documentation_options.js?v=c8100655"></script>
        <script src="../_static/doctools.js?v=9a2dae69"></script>
        <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../_static/js/theme.js"></script>
    <!-- begin favicon -->
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
    <link rel="manifest" href="/site.webmanifest" />
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
    <meta name="msapplication-TileColor" content="#355b95" />
    <meta name="theme-color" content="#ffffff" />
    <!-- end favicon -->
    
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Term and goal expansion" href="expansion.html" />
    <link rel="prev" title="Writing and running applications" href="programming.html" />
   
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="../index.html" class="icon icon-home">
            The Logtalk Handbook
              <img src="../_static/logtalk.gif" class="logo" alt="Logo"/>
          </a>
              <div class="version">
                3.93.0
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
    
              <p class="caption" role="heading"><span class="caption-text">Contents</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="index.html">User Manual</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="declarative.html">Declarative object-oriented programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="features.html">Main features</a></li>
<li class="toctree-l2"><a class="reference internal" href="nomenclature.html">Nomenclature</a></li>
<li class="toctree-l2"><a class="reference internal" href="messages.html">Messages</a></li>
<li class="toctree-l2"><a class="reference internal" href="objects.html">Objects</a></li>
<li class="toctree-l2"><a class="reference internal" href="protocols.html">Protocols</a></li>
<li class="toctree-l2"><a class="reference internal" href="categories.html">Categories</a></li>
<li class="toctree-l2"><a class="reference internal" href="predicates.html">Predicates</a></li>
<li class="toctree-l2"><a class="reference internal" href="inheritance.html">Inheritance</a></li>
<li class="toctree-l2"><a class="reference internal" href="events.html">Event-driven programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="threads.html">Multi-threading programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="errors.html">Error handling</a></li>
<li class="toctree-l2"><a class="reference internal" href="reflection.html">Reflection</a></li>
<li class="toctree-l2"><a class="reference internal" href="programming.html">Writing and running applications</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Printing messages and asking questions</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#printing-messages">Printing messages</a></li>
<li class="toctree-l3"><a class="reference internal" href="#message-tokenization">Message tokenization</a></li>
<li class="toctree-l3"><a class="reference internal" href="#meta-messages">Meta-messages</a></li>
<li class="toctree-l3"><a class="reference internal" href="#defining-message-prefixes-and-output-streams">Defining message prefixes and output streams</a></li>
<li class="toctree-l3"><a class="reference internal" href="#defining-message-prefixes-and-output-files">Defining message prefixes and output files</a></li>
<li class="toctree-l3"><a class="reference internal" href="#intercepting-messages">Intercepting messages</a></li>
<li class="toctree-l3"><a class="reference internal" href="#asking-questions">Asking questions</a></li>
<li class="toctree-l3"><a class="reference internal" href="#intercepting-questions">Intercepting questions</a></li>
<li class="toctree-l3"><a class="reference internal" href="#multi-threading-applications">Multi-threading applications</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="expansion.html">Term and goal expansion</a></li>
<li class="toctree-l2"><a class="reference internal" href="documenting.html">Documenting</a></li>
<li class="toctree-l2"><a class="reference internal" href="debugging.html">Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="performance.html">Performance</a></li>
<li class="toctree-l2"><a class="reference internal" href="installing.html">Installing Logtalk</a></li>
<li class="toctree-l2"><a class="reference internal" href="migration.html">Prolog integration and migration</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../refman/index.html">Reference Manual</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devtools/index.html">Developer Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../libraries/index.html">Libraries</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ports/index.html">Ports</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributions/index.html">Contributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../bibliography.html">Bibliography</a></li>
<li class="toctree-l1"><a class="reference internal" href="../genindex.html">Index</a></li>
</ul>

    <p class="caption"><span class="caption-text">External Contents</span></p>
    <ul>
    <li class="toctree-l1"><a class="reference internal" href="../../apis/index.html">APIs</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://logtalk.org">Logtalk website</a></li>
    <li class="toctree-l1"><a class="reference internal" href="https://github.com/LogtalkDotOrg/logtalk3">GitHub repo</a></li>
    </ul>
  
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../index.html">The Logtalk Handbook</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="index.html">User Manual</a></li>
      <li class="breadcrumb-item active">Printing messages and asking questions</li>
      <li class="wy-breadcrumbs-aside">
              <a href="https://github.com/LogtalkDotOrg/logtalk3/blob/master/docs/handbook/sources/userman/printing.rst" class="fa fa-github"> Edit on GitHub</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="printing-messages-and-asking-questions">
<span id="printing-printing"></span><h1>Printing messages and asking questions<a class="headerlink" href="#printing-messages-and-asking-questions" title="Link to this heading"></a></h1>
<p>Applications, components, and libraries often print all sorts of messages.
These include banners, logging, debugging, and computation results messages.
But also, in some cases, user interaction messages. However, the authors of
applications, components, and libraries often cannot anticipate the context
where their software will be used and thus decide which and when messages
should be displayed, suppressed, or diverted. Consider the different
components in a Logtalk application development and deployment. At the base
level, you have the Logtalk compiler and runtime. The compiler writes
messages related to e.g. compiling and loading files, compiling
entities, and compilation warnings and errors. The runtime may write
banner messages or throw execution errors that may result in printing
human-level messages. The development environment can be console-based,
or you may be using a GUI tool such as PDT. In the latter case, PDT
needs to intercept the Logtalk compiler and runtime messages to present
the relevant information using its GUI. Then you have all the other
components in a typical application. For example, your own libraries and
third-party libraries. The libraries may want to print messages on their
own, e.g. banners, debugging information, or logging information. As you
assemble all your application components, you want to have the final
word on which messages are printed, where, and when. Uncontrolled message
printing by libraries could potentially disrupt application flow, expose
implementation details, spam the user with irrelevant details, or break
user interfaces.</p>
<p>The solution is to decouple the calls to print a message from the actual
printing of the output text. The same is true for calls to read user input.
By decoupling the call to input some data from the actual read of the data,
we can easily switch from, for example, a command-line interface to a GUI
input dialog or even automate providing the data (e.g., when automating
testing of the user interaction).</p>
<p>Logtalk provides a solution based on the <em>structured message printing
mechanism</em> that was introduced by Quintus Prolog, where it was apparently
implemented by Dave Bowen (thanks to Richard O’Keefe for the historical
bits). This mechanism gives the programmer full control of message printing,
allowing it to filter, rewrite, or redirect any message. Variations of this
mechanism can also be found in some Prolog systems, including SICStus Prolog,
SWI-Prolog, and YAP. Based on this mechanism, Logtalk introduces an extension
that also allows abstracting asking a user for input. Both mechanisms are
implemented by the <a class="reference external" href="../../apis/logtalk_0.html#logtalk-0" title="(in Logtalk APIs v3.93.0)"><span class="xref std std-ref">logtalk</span></a> built-in object and
described in this section. The message printing mechanism is extensively
used by the Logtalk compiler itself and by the developer tools. The
question-asking mechanism is used e.g. in the <a class="reference internal" href="../devtools/debugger.html"><span class="doc">debugger</span></a>
tool.</p>
<section id="printing-messages">
<span id="id1"></span><h2>Printing messages<a class="headerlink" href="#printing-messages" title="Link to this heading"></a></h2>
<p>The main predicate for printing a message is
<a class="reference internal" href="../refman/methods/print_message_3.html#methods-print-message-3"><span class="std std-ref">logtalk::print_message/3</span></a>.
A simple example, using the Logtalk runtime, is:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk::print_message(banner, core, banner).

Logtalk 3.23.0
Copyright (c) 1998-2018 Paulo Moura
yes
</pre></div>
</div>
<p>The first argument of the predicate is the kind of message that we
want to print. In this case, we use <code class="docutils literal notranslate"><span class="pre">banner</span></code> to indicate that
we are printing a product name and copyright banner. An extensive
list of message kinds is supported by default:</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">banner</span></code></dt><dd><p>banner messages (used e.g. when loading tools or main application
components; can be suppressed by setting the <a class="reference internal" href="programming.html#flag-report"><span class="std std-ref">report</span></a>
flag to <code class="docutils literal notranslate"><span class="pre">warnings</span></code> or <code class="docutils literal notranslate"><span class="pre">off</span></code>)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">help</span></code></dt><dd><p>messages printed in reply to the user asking for help (mostly for
helping port existing Prolog code)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">information</span></code> and <code class="docutils literal notranslate"><span class="pre">information(Group)</span></code></dt><dd><p>messages usually printed in reply to a user’s request for information</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">silent</span></code> and <code class="docutils literal notranslate"><span class="pre">silent(Group)</span></code></dt><dd><p>not printed by default (but can be intercepted using the
<code class="docutils literal notranslate"><span class="pre">message_hook/4</span></code> predicate)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">comment</span></code> and <code class="docutils literal notranslate"><span class="pre">comment(Group)</span></code></dt><dd><p>useful but usually not essential messages (can be suppressed by
setting the <a class="reference internal" href="programming.html#flag-report"><span class="std std-ref">report</span></a> flag to <code class="docutils literal notranslate"><span class="pre">warnings</span></code> or <code class="docutils literal notranslate"><span class="pre">off</span></code>)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">warning</span></code> and <code class="docutils literal notranslate"><span class="pre">warning(Group)</span></code></dt><dd><p>warning messages (generated e.g. by the compiler; can be suppressed
by turning off the <a class="reference internal" href="programming.html#flag-report"><span class="std std-ref">report</span></a> flag)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">error</span></code> and <code class="docutils literal notranslate"><span class="pre">error(Group)</span></code></dt><dd><p>error messages (generated e.g. by the compiler)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">debug,</span> <span class="pre">debug(Group)</span></code></dt><dd><p>debugging messages (by default, only printed when the <a class="reference internal" href="programming.html#flag-debug"><span class="std std-ref">debug</span></a>
flag is turned on; the <code class="docutils literal notranslate"><span class="pre">print_message/3</span></code> goals for these messages are
suppressed by the compiler when the <a class="reference internal" href="programming.html#flag-optimize"><span class="std std-ref">optimize</span></a> flag is
turned on)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">question,</span> <span class="pre">question(Group)</span></code></dt><dd><p>questions to a user</p>
</dd>
</dl>
<p>Using a compound term allows easy partitioning of messages of the same kind
in different groups. Note that you can define your own alternative message
kind identifiers for your own components, together with suitable definitions
for their associated prefixes and output streams.</p>
<p>The second argument of <code class="docutils literal notranslate"><span class="pre">print_message/3</span></code> represents the <em>component</em>
defining the message being printed. In this context, <em>component</em> is a generic
term that can designate, e.g., a tool, a library, or some sub-system in a large
application. In our example, the component name is <code class="docutils literal notranslate"><span class="pre">core</span></code>, identifying the
Logtalk compiler/runtime. This argument was introduced to provide multiple
namespaces for message terms and thus simplify programming-in-the-large by
allowing easy filtering of all messages from a specific component and also
avoiding conflicts when two components happen to define the same message term
(e.g., <code class="docutils literal notranslate"><span class="pre">banner</span></code>). Users should choose and use a unique name for a component,
which usually is the name of the component itself. For example, all messages
from the <a class="reference internal" href="../devtools/lgtunit.html"><span class="doc">lgtunit</span></a> tool use <code class="docutils literal notranslate"><span class="pre">lgtunit</span></code> for the component
argument. The compiler and runtime are interpreted as a single component
designated as <code class="docutils literal notranslate"><span class="pre">core</span></code>.</p>
<p>The third argument of <code class="docutils literal notranslate"><span class="pre">print_message/3</span></code> is the message itself, represented
by a term. In the above example, the message term is <code class="docutils literal notranslate"><span class="pre">banner</span></code>. Using a
term to represent a message instead of a string with the message text itself
has significant advantages. Notably, it allows using a compound term for
easy parameterization of the message text and simplifies machine processing,
localization of applications, and message interception. For example:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk::print_message(comment, core, redefining_entity(object, foo)).

% Redefining object foo
yes
</pre></div>
</div>
</section>
<section id="message-tokenization">
<h2>Message tokenization<a class="headerlink" href="#message-tokenization" title="Link to this heading"></a></h2>
<p>The use of message terms requires a solution for generating the actual text
of the messages. This is supported by defining grammar rules for the
<a class="reference internal" href="../refman/methods/message_tokens_2.html#methods-message-tokens-2"><span class="std std-ref">logtalk::message_tokens//2</span></a> multifile
non-terminal, which translates a message term, for a given component,
to a list of tokens. For example:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>message_tokens<span class="o">//</span><span class="m">2</span>).
<span class="p">:- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>message_tokens<span class="o">//</span><span class="m">2</span>).

logtalk<span class="o">::</span>message_tokens(redefining_entity(<span class="nv">Type</span>, <span class="nv">Entity</span>), core) <span class="o">--&gt;</span>
    [<span class="s">&#39;Redefining ~w ~q&#39;</span><span class="o">-</span>[<span class="nv">Type</span>, <span class="nv">Entity</span>], <span class="k">nl</span>].
</pre></div>
</div>
<p>The following tokens can be used when translating a message:</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">at_same_line</span></code></dt><dd><p>Signals a following part to a multi-part message with no line break
in between; this token is ignored when it’s not the first in the list
of tokens</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">tab(Expression)</span></code></dt><dd><p>Evaluate the argument as an arithmetic expression and write the resulting
number of spaces; this token is ignored when the number of spaces is not
positive</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">nl</span></code></dt><dd><p>Change line in the output stream</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">flush</span></code></dt><dd><p>Flush the output stream (by calling the <code class="docutils literal notranslate"><span class="pre">flush_output/1</span></code> standard
predicate)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">Format-Arguments</span></code></dt><dd><p><code class="docutils literal notranslate"><span class="pre">Format</span></code> must be an atom and <code class="docutils literal notranslate"><span class="pre">Arguments</span></code> must be a list of format
arguments (the token arguments are passed to a call to the
<code class="docutils literal notranslate"><span class="pre">format/3</span></code> de facto standard predicate)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">term(Term,</span> <span class="pre">Options)</span></code></dt><dd><p><code class="docutils literal notranslate"><span class="pre">Term</span></code> can be any term and <code class="docutils literal notranslate"><span class="pre">Options</span></code> must be a list of valid
<code class="docutils literal notranslate"><span class="pre">write_term/3</span></code> output options (the token arguments are passed to a
call to the <code class="docutils literal notranslate"><span class="pre">write_term/3</span></code> standard predicate)</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">ansi(Attributes,</span> <span class="pre">Format,</span> <span class="pre">Arguments)</span></code></dt><dd><p>Taken from SWI-Prolog; by default, do nothing; can be used for styled
output</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">begin(Kind,</span> <span class="pre">Var)</span></code></dt><dd><p>Taken from SWI-Prolog; by default, do nothing; can be used together
with <code class="docutils literal notranslate"><span class="pre">end(Var)</span></code> to wrap a sequence of message tokens</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">end(Var)</span></code></dt><dd><p>Taken from SWI-Prolog; by default, do nothing</p>
</dd>
</dl>
<p>The <code class="docutils literal notranslate"><span class="pre">logtalk</span></code> object also defines public predicates for printing a list
of tokens, for hooking into printing an individual token, and for setting
default output streams and message prefixes. For example, the SWI-Prolog
adapter file uses the print message token hook predicate to enable coloring
of messages printed on a console.</p>
</section>
<section id="meta-messages">
<h2>Meta-messages<a class="headerlink" href="#meta-messages" title="Link to this heading"></a></h2>
<p>Defining tokenization rules for every message is not always necessary, however.
Logtalk defines several <em>meta-messages</em> that are handy for simple cases and
temporary messages only used during application development, notably debugging
messages. See the <a class="reference internal" href="debugging.html#debugging-messages"><span class="std std-ref">Debugging messages</span></a> section and the
<a class="reference external" href="../../apis/logtalk_0.html#logtalk-0" title="(in Logtalk APIs v3.93.0)"><span class="xref std std-ref">logtalk built-in object</span></a> remarks section for details.</p>
</section>
<section id="defining-message-prefixes-and-output-streams">
<h2>Defining message prefixes and output streams<a class="headerlink" href="#defining-message-prefixes-and-output-streams" title="Link to this heading"></a></h2>
<p>The <a class="reference internal" href="../refman/methods/message_prefix_stream_4.html#methods-message-prefix-stream-4"><span class="std std-ref">logtalk::message_prefix_stream/4</span></a>
hook predicate can be used to define a message line prefix and an output stream
for printing messages of a given kind and component. For example:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>message_prefix_stream<span class="o">/</span><span class="m">4</span>).
<span class="p">:- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>message_prefix_stream<span class="o">/</span><span class="m">4</span>).

logtalk<span class="o">::</span>message_prefix_stream(comment, my_app, <span class="s">&#39;% &#39;</span>, user_output).
logtalk<span class="o">::</span>message_prefix_stream(warning, my_app, <span class="s">&#39;* &#39;</span>, user_error).
</pre></div>
</div>
<p>A single clause at most is expected per message kind and component pair.
When this predicate is not defined for a given kind and component pair,
the following defaults are used:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span>kind_prefix_stream(banner,         <span class="s">&#39;&#39;</span>,       user_output).
kind_prefix_stream(help,           <span class="s">&#39;&#39;</span>,       user_output).
kind_prefix_stream(question,       <span class="s">&#39;&#39;</span>,       user_output).
kind_prefix_stream(question(<span class="nv">_</span>),    <span class="s">&#39;&#39;</span>,       user_output).
kind_prefix_stream(information,    <span class="s">&#39;% &#39;</span>,     user_output).
kind_prefix_stream(information(<span class="nv">_</span>), <span class="s">&#39;% &#39;</span>,     user_output).
kind_prefix_stream(comment,        <span class="s">&#39;% &#39;</span>,     user_output).
kind_prefix_stream(comment(<span class="nv">_</span>),     <span class="s">&#39;% &#39;</span>,     user_output).
kind_prefix_stream(warning,        <span class="s">&#39;*     &#39;</span>, user_error).
kind_prefix_stream(warning(<span class="nv">_</span>),     <span class="s">&#39;*     &#39;</span>, user_error).
kind_prefix_stream(error,          <span class="s">&#39;!     &#39;</span>, user_error).
kind_prefix_stream(error(<span class="nv">_</span>),       <span class="s">&#39;!     &#39;</span>, user_error).
kind_prefix_stream(debug,          <span class="s">&#39;&gt;&gt;&gt; &#39;</span>,   user_error).
kind_prefix_stream(debug(<span class="nv">_</span>),       <span class="s">&#39;&gt;&gt;&gt; &#39;</span>,   user_error).
</pre></div>
</div>
<p>When the message kind is unknown, <code class="docutils literal notranslate"><span class="pre">information</span></code> is used instead.</p>
</section>
<section id="defining-message-prefixes-and-output-files">
<h2>Defining message prefixes and output files<a class="headerlink" href="#defining-message-prefixes-and-output-files" title="Link to this heading"></a></h2>
<p>Some applications require copying and saving messages without diverting them
from their default stream. For simple cases, this can be accomplished by
intercepting the messages using the <a class="reference internal" href="../refman/methods/message_hook_4.html#methods-message-hook-4"><span class="std std-ref">logtalk::message_hook/4</span></a>
multifile hook predicate (see next section). In more complex cases, where
messages are already intercepted for a different purpose, it can be tricky
to use multiple definitions of the <code class="docutils literal notranslate"><span class="pre">message_hook/4</span></code> predicate as the
order of the clauses of a multiple predicate cannot be assumed in general
(for all <code class="docutils literal notranslate"><span class="pre">message_hook/4</span></code> predicate definitions to run, all but the last
one to be called must fail). Using a single <em>master</em> definition is also not
ideal as it would result in strong coupling instead of a clean separation of
concerns.</p>
<p>The experimental <a class="reference internal" href="../refman/methods/message_prefix_file_6.html#methods-message-prefix-file-6"><span class="std std-ref">logtalk::message_prefix_file/6</span></a>
hook predicate can be used to define a message line prefix and an output file
for copying messages of a given kind and component pair. For example:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>message_prefix_file<span class="o">/</span><span class="m">6</span>).
<span class="p">:- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>message_prefix_file<span class="o">/</span><span class="m">6</span>).

logtalk<span class="o">::</span>message_prefix_file(error,   app, <span class="s">&#39;! &#39;</span>, <span class="s">&#39;log.txt&#39;</span>, append, []).
logtalk<span class="o">::</span>message_prefix_file(warning, app, <span class="s">&#39;! &#39;</span>, <span class="s">&#39;log.txt&#39;</span>, append, []).
</pre></div>
</div>
<p>A single clause at most is expected per message kind and component pair.</p>
<p>This predicate is called by default by the message printing mechanism.
Definitions of the <code class="docutils literal notranslate"><span class="pre">message_hook/4</span></code> hook predicate are free to decide
if the <code class="docutils literal notranslate"><span class="pre">logtalk::message_prefix_file/6</span></code> predicate should be called and
acted upon.</p>
</section>
<section id="intercepting-messages">
<h2>Intercepting messages<a class="headerlink" href="#intercepting-messages" title="Link to this heading"></a></h2>
<p>Calls to the <a class="reference internal" href="../refman/methods/print_message_3.html#methods-print-message-3"><span class="std std-ref">logtalk::print_message/3</span></a>
predicate can be intercepted by defining clauses for the
<a class="reference internal" href="../refman/methods/message_hook_4.html#methods-message-hook-4"><span class="std std-ref">logtalk::message_hook/4</span></a> multifile
hook predicate. This predicate can suppress, rewrite, and divert messages.</p>
<p>As a first example, assume that you want to make Logtalk startup less verbose
by suppressing printing of the default compiler flag values. This can be
easily accomplished by defining the following category in a settings file:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">category</span>(my_terse_logtalk_startup_settings).

<span class="p">    :- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>message_hook<span class="o">/</span><span class="m">4</span>).
<span class="p">    :- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>message_hook<span class="o">/</span><span class="m">4</span>).

    logtalk<span class="o">::</span>message_hook(default_flags, comment(settings), core, <span class="nv">_</span>).

<span class="p">:- </span><span class="k">end_category</span>.
</pre></div>
</div>
<p>The printing message mechanism automatically calls the <code class="docutils literal notranslate"><span class="pre">message_hook/4</span></code>
hook predicate. When this call succeeds, the mechanism assumes that the
message has been successfully handled.</p>
<p>As another example, assume that you want to print all otherwise silent
compiler messages:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">category</span>(my_verbose_logtalk_message_settings).

<span class="p">    :- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>message_hook<span class="o">/</span><span class="m">4</span>).
<span class="p">    :- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>message_hook<span class="o">/</span><span class="m">4</span>).

    logtalk<span class="o">::</span>message_hook(<span class="nv">_Message</span>, silent, core, <span class="nv">Tokens</span>) <span class="o">:-</span>
        logtalk<span class="o">::</span>message_prefix_stream(comment, core, <span class="nv">Prefix</span>, <span class="nv">Stream</span>),
        logtalk<span class="o">::</span>print_message_tokens(<span class="nv">Stream</span>, <span class="nv">Prefix</span>, <span class="nv">Tokens</span>).

    logtalk<span class="o">::</span>message_hook(<span class="nv">_Message</span>, silent(<span class="nv">Key</span>), core, <span class="nv">Tokens</span>) <span class="o">:-</span>
        logtalk<span class="o">::</span>message_prefix_stream(comment(<span class="nv">Key</span>), core, <span class="nv">Prefix</span>, <span class="nv">Stream</span>),
        logtalk<span class="o">::</span>print_message_tokens(<span class="nv">Stream</span>, <span class="nv">Prefix</span>, <span class="nv">Tokens</span>).

<span class="p">:- </span><span class="k">end_category</span>.
</pre></div>
</div>
</section>
<section id="asking-questions">
<span id="printing-questions"></span><h2>Asking questions<a class="headerlink" href="#asking-questions" title="Link to this heading"></a></h2>
<p>Logtalk <em>structured question-asking</em> mechanism complements the message
printing mechanism. It provides an abstraction for the common task of
asking a user a question and reading back its reply. By default, this
mechanism writes the question, writes a prompt, and reads the answer
using the current user input and output streams but allows all steps to
be intercepted, filtered, rewritten, and redirected. Two typical examples
are using a GUI dialog for asking questions and automatically providing
answers to specific questions.</p>
<p>The question-asking mechanism works in tandem with the message printing
mechanism, using it to print the question text and a prompt. It provides
an asking predicate and a hook predicate, both declared and defined in
the <code class="docutils literal notranslate"><span class="pre">logtalk</span></code> built-in object. The asking predicate,
<a class="reference internal" href="../refman/methods/ask_question_5.html#methods-ask-question-5"><span class="std std-ref">logtalk::ask_question/5</span></a>,
is used for asking a question and reading the answer. Assume that we
defined the following message tokenization and question prompt and
stream:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">category</span>(hitchhikers_guide_to_the_galaxy).

<span class="p">    :- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>message_tokens<span class="o">//</span><span class="m">2</span>).
<span class="p">    :- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>message_tokens<span class="o">//</span><span class="m">2</span>).

    <span class="c">% abstract the question text using the atom ultimate_question;</span>
    <span class="c">% the second argument, hitchhikers, is the application component</span>
    logtalk<span class="o">::</span>message_tokens(ultimate_question, hitchhikers) <span class="o">--&gt;</span>
        [<span class="s">&#39;The answer to the ultimate question of life, the universe and everything is?&#39;</span><span class="o">-</span>[], <span class="k">nl</span>].

<span class="p">   :- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>question_prompt_stream<span class="o">/</span><span class="m">4</span>).
<span class="p">   :- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>question_prompt_stream<span class="o">/</span><span class="m">4</span>).

   <span class="c">% the prompt is specified here instead of being part of the question text</span>
   <span class="c">% as it will be repeated if the answer doesn&#39;t satisfy the question closure</span>
   logtalk<span class="o">::</span>question_prompt_stream(question, hitchhikers, <span class="s">&#39;&gt; &#39;</span>, user_input).

<span class="p">:- </span><span class="k">end_category</span>.
</pre></div>
</div>
<p>After compiling and loading this category, we can now ask the ultimate
question:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk::ask_question(question, hitchhikers, ultimate_question, &#39;==&#39;(42), N).

The answer to the ultimate question of life, the universe and everything is?
&gt; 42.

N = 42
yes
</pre></div>
</div>
<p>Note that the fourth argument, <code class="docutils literal notranslate"><span class="pre">'=='(42)</span></code> in our example, is a <a class="reference internal" href="../glossary.html#term-closure"><span class="xref std std-term">closure</span></a>
that is used to check the answers provided by the user. The question is repeated
until the goal constructed by extending the closure with the user answer
succeeds. For example:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk::ask_question(question, hitchhikers, ultimate_question, &#39;==&#39;(42), N).
The answer to the ultimate question of life, the universe and everything is?
&gt; icecream.
&gt; tea.
&gt; 42.

N = 42
yes
</pre></div>
</div>
<p>Practical usage examples of this mechanism can be found, e.g., in the
<code class="docutils literal notranslate"><span class="pre">debugger</span></code> tool where it’s used to abstract the user interaction when
tracing a goal execution in debug mode.</p>
</section>
<section id="intercepting-questions">
<h2>Intercepting questions<a class="headerlink" href="#intercepting-questions" title="Link to this heading"></a></h2>
<p>Calls to the <a class="reference internal" href="../refman/methods/ask_question_5.html#methods-ask-question-5"><span class="std std-ref">logtalk::ask_question/5</span></a>
predicate can be intercepted by defining clauses for the
<a class="reference internal" href="../refman/methods/question_hook_6.html#methods-question-hook-6"><span class="std std-ref">logtalk::question_hook/6</span></a> multifile
hook predicate. This predicate can suppress, rewrite, and divert questions.
For example, assume that we want to automate testing and thus cannot rely
on someone manually providing answers:</p>
<div class="highlight-logtalk notranslate"><div class="highlight"><pre><span></span><span class="p">:- </span><span class="k">category</span>(hitchhikers_fixed_answers).

<span class="p">    :- </span><span class="k">multifile</span>(logtalk<span class="o">::</span>question_hook<span class="o">/</span><span class="m">6</span>).
<span class="p">    :- </span><span class="k">dynamic</span>(logtalk<span class="o">::</span>question_hook<span class="o">/</span><span class="m">6</span>).

    logtalk<span class="o">::</span>question_hook(ultimate_question, question, hitchhikers, <span class="nv">_</span>, <span class="nv">_</span>, <span class="m">42</span>).

<span class="p">:- </span><span class="k">end_category</span>.
</pre></div>
</div>
<p>After compiling and loading this category, trying the question again will
now skip asking the user:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk::ask_question(question, hitchhikers, ultimate_question, &#39;==&#39;(42), N).

N = 42
yes
</pre></div>
</div>
<p>In a practical case, the fixed answer would be used for follow-up goals
being tested. The question-answer read loop (which calls the question
check closure) is not used when a fixed answer is provided using the
<code class="docutils literal notranslate"><span class="pre">logtalk::question_hook/6</span></code> predicate thus preventing the creation
of endless loops. For example, the following query succeeds:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>| ?- logtalk::ask_question(question, hitchhikers, ultimate_question, &#39;==&#39;(41), N).

N = 42
yes
</pre></div>
</div>
<p>Note that the <code class="docutils literal notranslate"><span class="pre">logtalk::question_hook/6</span></code> predicate takes as argument
the closure specified in the <code class="docutils literal notranslate"><span class="pre">logtalk::ask_question/5</span></code> call, allowing
a fixed answer to be checked before being returned.</p>
</section>
<section id="multi-threading-applications">
<h2>Multi-threading applications<a class="headerlink" href="#multi-threading-applications" title="Link to this heading"></a></h2>
<p>When writing multi-threading applications, user-defined predicates calling
methods such as <code class="docutils literal notranslate"><span class="pre">print_message/3</span></code> or <code class="docutils literal notranslate"><span class="pre">ask_question/5</span></code> may need to be
declared synchronized in order to avoid race conditions.</p>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="programming.html" class="btn btn-neutral float-left" title="Writing and running applications" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="expansion.html" class="btn btn-neutral float-right" title="Term and goal expansion" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 1998-2025, Paulo Moura.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>